﻿using SafeLoad.NControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace FPSO.HMI.Pipe
{
    class ThreePointElement : IPipeElement
    {
        public ThreePointElement(NPipeLineThree threePoint) : base()
        {
            ThreePoint = threePoint;
            Port1 = null;
            Port2 = null;
            Port3 = null;
            Pos = new Point(Canvas.GetLeft(threePoint) + threePoint.ActualWidth / 2,
                Canvas.GetTop(threePoint) + threePoint.ActualHeight / 2);

            int angle = 0;
            if (threePoint.RenderTransform is RotateTransform rotate)
            {
                angle = (int)rotate.Angle;
            }

            double pipeWidth = threePoint.PipeWidth;
            double topX = Canvas.GetLeft(threePoint);
            double topY = Canvas.GetTop(threePoint);

            if (angle == -90)
            {
                //Right
                Port1Pos = new Point(topX + pipeWidth / 2, topY);
                Port2Pos = new Point(topX + threePoint.ActualWidth, topY + threePoint.ActualHeight / 2);
                Port3Pos = new Point(topX + pipeWidth / 2, topY + threePoint.ActualHeight);
            }
            else if (angle == 0)
            {
                //Bottom
                Port1Pos = new Point(topX + threePoint.ActualHeight, topY + pipeWidth / 2);
                Port2Pos = new Point(topX + threePoint.ActualHeight / 2, topY + threePoint.ActualWidth / 2);
                Port3Pos = new Point(topX, topY + pipeWidth / 2);
            }
            else if (angle == 180)
            {
                //Top
                Port1Pos = new Point(topX, topY + threePoint.ActualWidth - pipeWidth / 2);
                Port2Pos = new Point(topX + threePoint.ActualHeight / 2, topY);
                Port3Pos = new Point(topX + threePoint.ActualHeight, topY + threePoint.ActualWidth - pipeWidth / 2);
            }   
            else if (angle == 90)
            {
                //Left
                Port1Pos = new Point(topX + threePoint.ActualWidth - pipeWidth / 2, topY + threePoint.ActualHeight);
                Port2Pos = new Point(topX, topY + threePoint.ActualHeight / 2);
                Port3Pos = new Point(topX + threePoint.ActualWidth - pipeWidth / 2, topY);
            }
        }

        public IPipeElement Port1 { get; set; } 
        public IPipeElement Port2 { get; set; }
        public IPipeElement Port3 { get; set; }
        public NPipeLineThree ThreePoint { get; private set; }

        public Point Pos { get; private set; }
        public Point Port1Pos { get; private set; }
        public Point Port2Pos { get; private set; }
        public Point Port3Pos { get; private set; }

        public PortState Port1State { get; private set; }
        public PortState Port2State { get; private set; }
        public PortState Port3State { get; private set; }
        public override void UpdateUI()
        {
            bool active;
            double speed;

            active = Port1State != PortState.Stop && Port2State != PortState.Stop && Port1State != Port2State;
            speed = Port1State == PortState.In ? -0.35d : 0.35d;
            if (active != ThreePoint.PipeLineActive3)
            {
                ThreePoint.PipeLineActive3 = active;
            }
            if (Math.Abs(ThreePoint.MoveSpeed3 - speed) > 0.1)
            {
                ThreePoint.MoveSpeed3 = speed;
            }

            active = Port1State != PortState.Stop && Port3State != PortState.Stop && Port1State != Port3State;
            speed = Port1State == PortState.In ? 0.35 : -0.35;
            if (active != ThreePoint.PipeLineActive1)
            {
                ThreePoint.PipeLineActive1 = active;
            }
            if (Math.Abs(ThreePoint.MoveSpeed1 - speed) > 0.1)
            {
                ThreePoint.MoveSpeed1 = speed;
            }

            active = Port2State != PortState.Stop && Port3State != PortState.Stop && Port2State != Port3State;
            speed = Port2State == PortState.In ? 0.35 : -0.35;
            if (active != ThreePoint.PipeLineActive2)
            {
                ThreePoint.PipeLineActive2 = active;
            }
            if (Math.Abs(ThreePoint.MoveSpeed2 - speed) > 0.1)
            {
                ThreePoint.MoveSpeed2 = speed;
            }    

            //if (Port1State != PortState.Stop && Port2State != PortState.Stop && Port1State != Port2State)
            //{
            //    ThreePoint.PipeLineActive3 = true;
            //    ThreePoint.MoveSpeed3 = Port1State == PortState.In ? -0.35 : 0.35;
            //}
            //else
            //{
            //    ThreePoint.PipeLineActive3 = false;
            //}

            //if (Port1State != PortState.Stop && Port3State != PortState.Stop && Port1State != Port3State)
            //{
            //    ThreePoint.PipeLineActive1 = true;
            //    ThreePoint.MoveSpeed1 = Port1State == PortState.In ? 0.35 : -0.35;
            //}
            //else
            //{
            //    ThreePoint.PipeLineActive1 = false;
            //}

            //if (Port2State != PortState.Stop && Port3State != PortState.Stop && Port2State != Port3State)
            //{
            //    ThreePoint.PipeLineActive2 = true;
            //    ThreePoint.MoveSpeed2 = Port2State == PortState.In ? 0.35 : -0.35;
            //}
            //else
            //{
            //    ThreePoint.PipeLineActive2 = false;
            //}
        }
        public void Connect(PipeLineElement pipeLine)
        {
            bool flag = false;
            double dis1 = 0;
            double dis2 = 0;
            double dis3 = 0;
            if (PointDistance.Distance(Pos, pipeLine.Port1Pos) < 20 && pipeLine.Port1 == null)
            {
                flag = true;
                pipeLine.Port1 = this;
                dis1 = PointDistance.Distance(pipeLine.Port1Pos, Port1Pos);
                dis2 = PointDistance.Distance(pipeLine.Port1Pos, Port2Pos);
                dis3 = PointDistance.Distance(pipeLine.Port1Pos, Port3Pos);
            }
            else if (PointDistance.Distance(Pos, pipeLine.Port2Pos) < 20 && pipeLine.Port2 == null)
            {
                flag = true;
                pipeLine.Port2 = this;
                dis1 = PointDistance.Distance(pipeLine.Port2Pos, Port1Pos);
                dis2 = PointDistance.Distance(pipeLine.Port2Pos, Port2Pos);
                dis3 = PointDistance.Distance(pipeLine.Port2Pos, Port3Pos);
            }

            if (flag)
            {
                if (dis1 < dis2 && dis1 < dis3)
                {
                    Port1 = pipeLine;
                }
                else if (dis2 < dis1 && dis2 < dis3)
                {
                    Port2 = pipeLine;
                }
                else if (dis3 < dis1 && dis3 < dis2)
                {
                    Port3 = pipeLine;
                }
            }
        }
        public override void ResetState()
        {
            Port1State = PortState.Stop;
            Port2State = PortState.Stop;
            Port3State = PortState.Stop;
        }

        public override void SetInPort(IPipeElement element)
        {
            if (Port1 == element)
            {
                Port1State = PortState.In;
            }
            else if (Port2 == element)
            {
                Port2State = PortState.In;
            }
            else if (Port3 == element)
            {
                Port3State = PortState.In;
            }
        }

        public override void SetOutPort(IPipeElement element)
        {
            if (Port1 == element)
            {
                Port1State = PortState.Out;
            }
            else if (Port2 == element)
            {
                Port2State = PortState.Out;
            }
            else if (Port3 == element)
            {
                Port3State = PortState.Out;
            }
        }

    }
}
